using System.Linq;
using System.Web.Mvc;
using good1.ApplicationServices.Interface;
using good1.Core;
using good1.Core.Enums;
using good1.Web.Controllers.Attributes;
using good1.Web.Controllers.Infrastructure;
using good1.Web.Controllers.Infrastructure.Cookies;
using SharpArch.Web.NHibernate;
using SharpArch.Web.CommonValidator;
using SharpArch.Core;

namespace good1.Web.Controllers
{

    [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
    public class LocationsController : BaseController
    {
        public LocationsController(ILocationService<Location> locationService, ISecurityContextService securityContext) : base(securityContext)
        {
            Check.Require(locationService != null, "locationRepository may not be null");

            this.locationService = locationService;
        }

        [Transaction]
        public ActionResult Index() {
            IQueryable<Location> locations = locationService.GetAllSorted();
            return View(locations);
        }

        [Transaction]
        public ActionResult Show(int id) {
            Location location = locationService.Get(id);
            return View(location);
        }

        [Authorize]
        public ActionResult Create() {
            Location loc = locationService.GetCreation();
            return View(loc);
        }

        public ActionResult Map(int id)
        {
            if (id == 0) return null;
            var map = locationService.GetMapsByLocationId(id);
            return Json(map);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Location location, FormCollection formCollection)
        {
            ReadFormCollectionIntoDto(location, formCollection);
            location.Countries = null;
            if (location.IsValid()) {
                locationService.SaveOrUpdate(location);

                TempData["message"] = "The location was successfully created.";
                return RedirectToAction("Index");
            }

            MvcValidationAdapter.TransferValidationMessagesTo(ViewData.ModelState,
                location.ValidationResults());
            return View();
        }

        [Transaction]
        public ActionResult Edit(int id) {
            Location location = locationService.Get(id);
            return View(location);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, [ModelBinder(typeof(DefaultModelBinder))] Location location, FormCollection formCollection) {
            Location locationToUpdate = locationService.Get(id);
            TransferFormValuesTo(locationToUpdate, location);
            ReadFormCollectionIntoDto(locationToUpdate, formCollection);

            if (locationToUpdate.IsValid()) {
                TempData["message"] = "The location was successfully updated.";
                return RedirectToAction("Index");
            }
            else {
                locationService.RollbackTransaction();
                MvcValidationAdapter.TransferValidationMessagesTo(ViewData.ModelState, 
                    locationToUpdate.ValidationResults());
                return View(locationToUpdate);
            }
        }

        private void TransferFormValuesTo(Location locationToUpdate, Location locationFromForm) {
			locationToUpdate.Place = locationFromForm.Place;
			locationToUpdate.Country = locationFromForm.Country;
            locationToUpdate.LatLng = locationFromForm.LatLng;
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id)
        {
            TempData["Message"] = locationService.Delete(id);
            return RedirectToAction("Index");
        }

        private void ReadFormCollectionIntoDto(Location location, FormCollection formCollection)
        {
            location.Country = !string.IsNullOrEmpty(formCollection["CountryList"]) ?
               locationService.GetCountry(int.Parse(formCollection["CountryList"])) : null;
        }

        private readonly ILocationService<Location> locationService;
    }
}
